package com.dbsop.domain;

import com.dbsop.EsClient;
import com.dbsop.common.enums.FlagConnect;
import com.dbsop.common.enums.Order;
import com.dbsop.common.util.FieldUtils;
import java.util.*;
import java.util.stream.Collectors;

/**
 * Es条件查询
 */
public abstract class EsCondition {


    protected List<AbsConditionQuery> conditions = new ArrayList<AbsConditionQuery>();

    protected Set<String> fields = new HashSet<String>();

    protected List<String> indices = new ArrayList<>();

    protected List<EsOrder> esOrders = new ArrayList<EsOrder>();

    protected Ranking ranking;

    protected int size = 10000;

    protected Integer from = 0;

    public <T extends AbsConditionQuery> List<T> getConditions() {
        return (List<T>) conditions;
    }

    public static EsCondition getEsCondition(){
        boolean useHttp = EsClient.getEsClient().isUseHttp();
        if (!useHttp){
            return new com.dbsop.domain.transport.EsTransportCondition();
        }
        return new com.dbsop.domain.rest.EsRestCondition();

    }


    public List<EsOrder> getEsOrders() {
        return esOrders;
    }

    public Ranking getRanking() {
        return ranking;
    }

    public String[] getIndices() {
        return FieldUtils.converList(this.indices);
    }

    public int getSize() {
        return size;
    }

    public Set<String> getFields() {
        return fields;
    }


    public EsCondition from(int from){
        this.from = from;
        return this;
    }

    /**
     * 数据开始
     * @return
     */
    public Integer getFrom() {
        return from;
    }

    /**
     *  设置操作的索引
     * @param indices
     * @return
     */
    public EsCondition addIndex(String... indices){
        if (indices == null || indices.length ==0){
            return this;
        }
        for (String index : indices) {
            this.indices.add(index);
        }
        return this;
    }

    /**
     * 结果集排序
     * @param fields
     * @param order
     * @return
     */

    public abstract EsCondition queryOrder(Order order, String... fields);
    /**
     * 于等于
     * @param field
     * @param value
     * @return
     */
    public abstract EsConditionGtRange lte(String field, Object value);
    /**
     * 小于
     * @param field
     * @param value
     * @return
     */
    public abstract EsConditionGtRange lt(String field,Object value);

    /**
     * 大于等于
     * @param field
     * @param value
     * @return
     */
    public abstract EsConditionLtRange gte(String field, Object value);


    /**
     * 大于
     * @param field
     * @param value
     * @return
     */
    public abstract EsConditionLtRange gt(String field, Object value);

    /**
     * 于等于
     * @param field
     * @param value
     * @return
     */
    public abstract EsCondition LTE(String field, Object value);
    /**
     * 小于
     * @param field
     * @param value
     * @return
     */
    public abstract EsCondition LT(String field, Object value);

    /**
     * 大于等于
     * @param field
     * @param value
     * @return
     */
    public abstract EsCondition GTE(String field, Object value);


    /**
     * 大于
     * @param field
     * @param value
     * @return
     */
    public abstract EsCondition GT(String field, Object value);

    /**
     * 相等
     * @param field
     * @param value
     * @return
     */
    public abstract EsCondition eq(String field, Object value);

    /**
     * 模糊查询
     * @param field
     * @param value
     * @return
     */
    public abstract EsCondition like(String field, String value);

    /**
     *  IN查询
     * @param field
     * @return
     */
    public abstract EsCondition in(String field, Object... values);

    /**
     *  IN查询
     * @param field
     * @return
     */
    public abstract EsCondition in(String field, Collection values);

    /**
     * 进行排名
     * @param groupField
     * @param sortField
     * @param order
     * @param size
     * @return
     */
    public abstract EsCondition ranking(String groupField, String  sortField, Order order, int size);

    /**
     * 分词检索
     * @param field
     * @param values
     * @return
     */
    public abstract EsCondition analyze(String field, String analyze, String... values);
    /**
     * 分词检索
     * @param field
     * @param values
     * @return
     */
    public abstract EsCondition analyze(String field, String analyze, Collection<String> values);

    /**
     *  and 链接
     * @return
     */
    public EsCondition and(){
        if (conditions.size() !=0){
            conditions.get(conditions.size()-1).setFlagConnect(FlagConnect.AND);
        }
        return this;
    }

    /**
     *  OR 链接
     * @return
     */
    public EsCondition or(){
        if (conditions.size() !=0){
            conditions.get(conditions.size()-1).setFlagConnect(FlagConnect.OR);
        }
        return this;
    }

    /**
     *  NOT 链接
     * @return
     */
    public EsCondition not(){
        if (conditions.size() !=0){
            conditions.get(conditions.size()-1).setFlagConnect(FlagConnect.NOT);
        }
        return this;
    }

    /**
     *  and 链接
     * @return
     */
    public EsCondition subAnd(){
        if (conditions.size() !=0){
            conditions.get(conditions.size()-1).setSubConnect(FlagConnect.AND);
        }
        return this;
    }

    /**
     *  OR 链接
     * @return
     */
    public EsCondition subOr(){
        if (conditions.size() !=0){
            conditions.get(conditions.size()-1).setSubConnect(FlagConnect.OR);
        }
        return this;
    }

    /**
     *  NOT 链接
     * @return
     */
    public EsCondition subNot(){
        if (conditions.size() !=0){
            conditions.get(conditions.size()-1).setSubConnect(FlagConnect.NOT);
        }
        return this;
    }


    public EsCondition size(int size){
        this.size = size;
        return this;
    }

    /**
     * 显示字段
     * @param fields
     * @return
     */
    public EsCondition addFields(String ... fields){
        for (String field : fields) {
            this.fields.add(field);
        }
        return this;
    }

    /**
     * 排序
     * @param order
     * @param fields
     * @return
     */
    public EsCondition order(Order order, String ... fields){
        esOrders.add(new EsOrder(Arrays.stream(fields).collect(Collectors.toList()),order));
        return this;
    }

    /**
     * 子查询
     * @return
     */
    public EsCondition subSearch(EsCondition esCondition, FlagConnect subConnect){
        if (this.conditions.size()>0){
            AbsConditionQuery conditionQuery = this.conditions.get(this.conditions.size()-1);
            conditionQuery.getSubConditions().add(new SubCondition(esCondition.getConditions(),subConnect));
        }else {
            esCondition.conditions.addAll(esCondition.getConditions());
        }
        return this;
    }

    /**
     * 子查询
     * @return
     */
    public EsCondition subSearch(EsCondition esCondition){
        if (this.conditions.size()>0){
            AbsConditionQuery conditionQuery = this.conditions.get(this.conditions.size()-1);
            conditionQuery.getSubConditions().add(new SubCondition(esCondition.getConditions(),FlagConnect.AND));
        }else {
            esCondition.conditions.addAll(esCondition.getConditions());
        }
        return this;
    }


}
